﻿using Dispatcher.Core.Models;
using Dispatcher.Core.Providers;
using MiniFox.Caching;
using MiniFox.Components;
using MiniFox.Infrastructure;
using MiniFox.Net;
using MiniFox.Net.Http;
using MiniFox.Platform.Applications;
using MiniFox.Platform.Applications.Auth;
using MiniFox.Platform.File.Models;
using MiniFox.Utility;
using System.Configuration;
using System.Threading.Tasks;
using TemplateEngine;

namespace Dispatcher.Core
{
    public abstract class EngineServiceBase : ApiServiceBase
    {
        public EngineServiceBase(SystemPrincipal principal) : base(principal)
        {

        }

        HttpAdapter tmplHttpAdapter;

        public HttpAdapter PlatformService
        {
            get
            {
                if (this.tmplHttpAdapter == null)
                {
                    var container = WebAdapterFactory.Container;
                    this.tmplHttpAdapter = container.GetHttpAdapterByName("platform");
                }
                return this.tmplHttpAdapter;
            }
        }

        [AutoWired]
        protected IUserProvider UserProvider
        {
            get;
            set;
        }

        [AutoWired]
        protected IAttachmentProvider AttachmentProvider
        {
            get;
            set;
        }

        protected virtual UserModel[] GetUsers(params string[] userId)
        {
            if (userId == null || userId.Length <= 0)
                return null;
            return userId.Select(id =>
            {
                var user = this.UserProvider.GetUser(id);
                if (user == null)
                {
                    user = new UserModel();
                    if (id.IsEmail())
                        user.SecEmail = id;
                    else if (id.IsPhoneNumber())
                        user.Cellphone = id;
                    else
                        user.LoginName = id;
                }
                return user;
            }).ToArray();
        }

        protected virtual U[] GetOpenAuthUser<U>(string authName, params string[] userIds) where U : class
        {
            List<U> users = [];
            foreach (var userId in userIds)
            {
                var user = this.UserProvider.GetOpenAuthUser<U>(authName, userId);
                if (user == null)
                    continue;
                users.Add(user);
            }

            return [.. users];
        }

        protected virtual async Task<string> GetBodyContentAsync(string templateName, object dataModel)
        {
            string body;
            if (string.IsNullOrWhiteSpace(templateName))
            {
                body = dataModel.ToString();
            }
            else
            {
                var service = this.PlatformService.GetService("resolveTmpl");
                
                var response = await service.PostAsync<object, Response<string>>(dataModel, new { name = templateName });
                body = response.Data;
            }
            return body;
        }
        protected virtual Task<string> GetBodyContentAsync(SendRequest sendRequest)
        {
            return GetBodyContentAsync(sendRequest.TemplateName, sendRequest.Data);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileIds"></param>
        /// <returns></returns>
        public virtual IEnumerable<FileData> GetAttachments(string[] fileIds)
        {
            List<FileData> fileDatas = [];
            Parallel.ForEach(fileIds, fileId =>
            {
                var fileData = CacheService.GetCacheObject<FileData>(fileId);
                if (fileData == null)
                    fileData = this.AttachmentProvider.LoadPreSave(fileId);
                if (fileData == null) return;
                fileDatas.Add(fileData);
            });
            return fileDatas;
        }
    }
}
